
/**
 *
 */
package com.serviceprovider.business.module.admin.transaction.services.dao.impl;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.admin.transaction.model.NewCsvReplica;
import com.serviceprovider.business.module.admin.transaction.services.dao.interfaces.ITransactionImportDataService;
import com.serviceprovider.business.module.admin.transaction.services.dao.interfaces.IValidationService;
import com.serviceprovider.business.module.admin.transaction.utility.StringUtils;
import com.serviceprovider.business.module.admin.transaction.valueobjects.TransactionCSV;
import com.serviceprovider.business.module.admin.transaction.valueobjects.TransactionCSVError;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

//~--- JDK imports ------------------------------------------------------------

import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author mrduongnv@gmail.com
 *
 */
@Repository("validationService")
public class ValidationService implements IValidationService {

    /** The transaction import data service. */
    @Autowired
    private ITransactionImportDataService transactionImportDataService;

    /**
     * {@inheritDoc}
     */
    @Override
    public void checkForCreditOrDebit(NewCsvReplica transaction, TransactionCSVError csvError, String value,
                                      String field) {
        if (StringUtils.isEmpty(value)) {
            if (getRequiredFieldList().contains(field)) {
                createError(transaction, csvError, field);
            }
        } else if (!StringUtils.isCreditOrDebit(value)) {
            createError(transaction, csvError, field);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void checkForDigit(NewCsvReplica transaction, TransactionCSVError csvError, String value, String field) {
        if (StringUtils.isEmpty(value)) {
            if (getRequiredFieldList().contains(field)) {
                createError(transaction, csvError, field);
            }
        } else if (!StringUtils.isAllDigits(value)) {
            createError(transaction, csvError, field);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void checkForString(NewCsvReplica transaction, TransactionCSVError csvError, String value, String field) {
        if (StringUtils.isEmpty(value) && getRequiredFieldList().contains(field)) {
            createError(transaction, csvError, field);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void checkForUniqueNumber(NewCsvReplica transaction, TransactionCSVError csvError, String value,
                                     String field) {
        if (StringUtils.isEmpty(value)) {
            if (getRequiredFieldList().contains(field)) {
                createError(transaction, csvError, field);
            }
        } else if (!StringUtils.isAllDigits(value)) {
            createError(transaction, csvError, field);
        } else if (isDuplicated(value)) {
            createError(transaction, csvError, field);
            csvError.setDuplicated(true);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void checkForValidDate(NewCsvReplica transaction, TransactionCSVError csvError, String date, String pattern,
                                  String field) {
        if (!StringUtils.isEmpty(date)) {
            SimpleDateFormat format = new SimpleDateFormat(pattern);

            try {
                format.parse(date);
            } catch (Exception e) {
                createError(transaction, csvError, field);
            }
        } else if (getRequiredFieldList().contains(field)) {
            createError(transaction, csvError, field);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void checkIdentificationNumber(NewCsvReplica transaction, TransactionCSVError csvError,
            String identificationNumber) {
        final Map<String, String> originatorCodeAndSSNMap =
            StringUtils.extractOriginatorCodeAndSSN(identificationNumber);

        if (originatorCodeAndSSNMap != null) {
            final String ssn            = originatorCodeAndSSNMap.get("ssn");
            final String originatorCode = originatorCodeAndSSNMap.get("originatorCode");

            if (StringUtils.isEmpty(ssn) && getRequiredFieldList().contains("ssn")) {
                createError(transaction, csvError, "ssn");
            }

            if (StringUtils.isEmpty(originatorCode) && getRequiredFieldList().contains("originatorCode")) {
                createError(transaction, csvError, "originatorCode");
            }

            // transaction.setSsn(ssn);
            transaction.setOrginator_code(originatorCode);
        } else if (getRequiredFieldList().contains("identificationNumber")) {
            createError(transaction, csvError, "identificationNumber");
        }
    }

    /**
     * Creates the error.
     *
     * @param transaction
     *            the transaction csv
     * @param csvError
     *            the csv error
     * @param field
     *            the field
     */
    private void createError(NewCsvReplica transaction, TransactionCSVError csvError, String field) {
        if (csvError.getTransaction() == null) {
            csvError.setTransaction(transaction);
        }

        csvError.getFields().add(field);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isDuplicated(String receiverAccount) {
        return this.transactionImportDataService.checkIfTransactionPresent(receiverAccount);
    }

    private List<String> getRequiredFieldList() {
        List<String> requiredList = new ArrayList<String>();

        requiredList.add("receiverAccount");
        requiredList.add("traceNumber");

        return requiredList;
    }
}



